package com.wsl.demo.config;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * @author user
 */
@Component
public class AccessLimitInterceptor extends HandlerInterceptorAdapter {

    @Resource
    private RedisTemplate<String,Integer> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setContentType("text/html;charset=utf-8");
        //真实先获取token
        String token = "test001";

        String result = accessLimit(token, handler);
        if (!StringUtils.isEmpty(result)){
            response.sendError(401,result);
            return false;
        }
        return true;
    }

    private String accessLimit(String token,Object handler){
        String key = RedisEnum.USER_VISIT_COUNT+token;
        //判断请求是否属于方法的请求
        if(handler instanceof HandlerMethod){
            HandlerMethod hm = (HandlerMethod) handler;
            //获取方法中的注解
            AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
            if(accessLimit == null){
                return null;
            }
            int time = accessLimit.time();
            int maxCount = accessLimit.maxCount();
            TimeUnit timeUnit = accessLimit.timeUnit();
            String msg = accessLimit.msg();

            Integer count = redisTemplate.opsForValue().get(key);
            if(count == null){
                redisTemplate.opsForValue().set(key,1,time, timeUnit);
            }else if(count <= maxCount){
                redisTemplate.opsForValue().increment(key);
            }else{
                return msg;
            }
        }
        return null;
    }

}